---@type BattleEntityBar
local BattleEntityBar = require("View/UIBattle/SubPanel/BattleEntityBar")
---@class UIBattleEntityLayer : UIBase
UIBattleEntityLayer = UIBase.New(PanelNames.UIBattleEntityLayer)
local t = UIBattleEntityLayer

function t:OnCreate()
    ---@type BattleEntityBar[]
    self.entityItemList = {}
    self.damageItemList = {}
    self.cacheDamageItemList = {}
    local actorList = Battle.ActorManager.GetActorList()
    for k,v in pairs(actorList) do
        self:CreateItem(v)
    end
    self.damageData = {}

    self:RegisterBattleEvent()
    Battle.ClientBattle:RegisterLateUpdateCallback(self.LateUpdateCallback,self)
end

function t:OnDestroy()
    for k,v in pairs(self.entityItemList) do
        v:OnDestroy()
    end
    self.entityItemList = nil
    self.damageItemList = nil
    self.cacheDamageItemList = nil
    self:UnRegisterBattleEvent()
end
function t:RegisterBattleEvent()
    Battle.GlobalEventSystem.Register(Battle.Event.ActorDead,self.ActorDead,self)
    Battle.GlobalEventSystem.Register(Battle.Event.ActorCreate,self.ActorCreate,self)
    Battle.GlobalEventSystem.Register(Battle.Event.PlayerHpChanged,self.HpChanged,self)
    Battle.GlobalEventSystem.Register(Battle.Event.CameraPosChanged, self.CameraPosChanged,self)
    Battle.GlobalEventSystem.Register(Battle.Event.ActorDamageShow,self.DamageShow,self)
end
function t:UnRegisterBattleEvent()
    Battle.GlobalEventSystem.UnRegister(Battle.Event.ActorDead,self.ActorDead,self)
    Battle.GlobalEventSystem.UnRegister(Battle.Event.ActorCreate,self.ActorCreate,self)
    Battle.GlobalEventSystem.UnRegister(Battle.Event.PlayerHpChanged,self.HpChanged,self)
    Battle.GlobalEventSystem.UnRegister(Battle.Event.CameraPosChanged, self.CameraPosChanged,self)
    Battle.GlobalEventSystem.Register(Battle.Event.ActorDamageShow,self.DamageShow,self)
end
---@param entity Battle.Entity
function t:CreateItem(entity)
    if entity.actorType == Battle.ActorType.Lord then
        return
    end
    local item = self.entityItemList[entity:GetId()]
    if item then return end
    local obj = newGComponent("UIBattle","Com_HeroHp")
    item = BattleEntityBar.New()
    item:OnCreate(obj)
    item:Refresh(entity)
    self.entityItemList[entity:GetId()] = item
    self.fguiObj:AddChild(obj)
end
function t:GetItem(id)
    return self.entityItemList[id]
end
function t:GetDamageItem()
    if #self.cacheDamageItemList > 0 then
        local item = table.remove(self.cacheDamageItemList)
        item.time = 0.5
        return item
    end
    local obj = newGComponent("UIBattle","Com_DamageText")
    local ctrlType = obj:GetController("damageType")
    self.fguiObj:AddChild(obj)
    return {obj = obj,time = 0.5,ctrlType = ctrlType}
end

--region 消息处理
---@param args BattleEvent
function t:HpChanged(args)
    local defender = args.sender
    local item = self.entityItemList[defender:GetId()]
    if item then
        item:SetHp(defender:GetHp(),defender:GetHpMax())
    end
end
---@param args Battle.EntityDamageShowArgs
function t:DamageShow(args)

    local id = args.sender:GetId()
    for k,v in pairs(self.damageItemList) do
        if v.entityId == id and v.time > 0.4 then
            v.obj.y = v.obj.y - 20
        end
    end

    local damageItem = self:GetDamageItem(args.damageShowType)
    damageItem.entityId = args.sender:GetId()
    local pos = Vector3.GetPool()
    local animName = "normal"
    pos:SetV(args.sender:GetHPBarPos())
    pos.y = pos.y + 0.1
    damageItem.ctrlType.selectedIndex = 0
    local textName = "Text_OrangeDamage"
    if args.damageShowType == Battle.DamageShowType.Treat then
        animName = "treat"
        textName = "Text_GreenHeal"
        damageItem.ctrlType.selectedIndex = 1
    elseif args.damageShowType == Battle.DamageShowType.Crit then
        animName = "crit"
        textName = "Text_RedCritical"
        damageItem.ctrlType.selectedIndex = 3
    elseif args.damageShowType == Battle.DamageShowType.Energy then
        pos:SetV(args.sender:GetPos())
        pos.y = args.sender.height/2
        textName = "Text_BlueEnergy"
        damageItem.ctrlType.selectedIndex = 2
    end
    damageItem.animName = animName
    damageItem.obj:GetTransition(animName):Play()
    local op = args.damage > 0 and "-" or "+"
    damageItem.obj:GetChild(textName).text = op.. math.abs(math.floor(args.damage))

    Util.WorldToFGUILocal(Battle.SceneMgr.camera,pos.x,pos.y,pos.z,damageItem.obj)
    table.insert(self.damageItemList,damageItem)
    Vector3.ReturnPool(pos)
end
---@param args BattleEvent
function t:ActorDead(args)
    local item = self:GetItem(args.dead:GetId())
    if not item then return end
    item:SetVisible(false)
    self:DestroyActorItem(item)
end

---@param args BattleEvent
function t:ActorCreate(args)
    self:CreateItem(args.sender)
end
function t:CameraPosChanged()
    for k,v in pairs(self.entityItemList) do
        v:Update(0)
    end
end
function t:LateUpdateCallback(dt)
    for k,v in pairs(self.entityItemList) do
        v:Update(dt)
    end
    for k,v in pairs(self.damageItemList) do
        v.time = v.time - dt
        if v.time < 0 then
            table.insert(self.cacheDamageItemList,v)
            self.damageItemList[k] = nil
        end
    end
end

---@param item BattleEntityBar
function t:DestroyActorItem(item)
    if not item then return end
    item:OnDestroy()
    self.entityItemList[item.entityId] = nil
end
--endregion 消息处理
return t